package com.tianji.promotion.util;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Aspect
public class MyLockAdvice {

    @Autowired
    private RedissonClient client;

    @Autowired
    private MyLockFactory lockFactory;

    @Around("@annotation(myLock)")
    public Object tryLock(ProceedingJoinPoint pjp, MyLock myLock) throws Throwable {
        // 根据名称获取一把锁
        boolean locked = false;
        // 使用工厂模式获取锁
        RLock lock = lockFactory.getLock(myLock.lockType(), myLock.name());
        try{
            // 尝试加锁
            locked = lock.tryLock(myLock.waitTime(), myLock.leaseTime(), myLock.unit());
            // 判断结果
            if(!locked){
                log.info("获取分布式锁失败");
                return null;
            }
            // 如果成功，执行业务逻辑，否则，啥也不干
            log.info("获取分布式锁成功");
            return pjp.proceed();
        }catch(Exception e){
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }finally {
            // 释放锁
            if(locked){
                log.info("释放分布式锁");
                lock.unlock();
            }
        }
    }
}
